/**
* <p>Title: platform.util.java</p>
* <p>Description: </p>
* <p>Company: www.huoyunren.com</p>
* @author duanxiangyun
* @date 2018年4月18日
* @version 1.0
*/
package com.hxbd.test.utils;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.eclipse.jetty.util.ConcurrentHashSet;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.testng.Assert;
import org.testng.ITestResult;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aventstack.extentreports.ExtentReports;
import com.aventstack.extentreports.ExtentTest;
import com.aventstack.extentreports.ExtentTestInterruptedException;
import com.aventstack.extentreports.model.Test;
import com.aventstack.extentreports.reporter.ExtentHtmlReporter;
import com.aventstack.extentreports.reporter.ExtentXReporter;
import com.aventstack.extentreports.reporter.configuration.ChartLocation;
import com.aventstack.extentreports.reporter.configuration.Theme;
import com.duan.test.utils.common.CommonUtils;
import com.hxbd.service.UtilService;
import com.hxbd.test.Beans.TestDicBean;
import com.hxbd.test.handles.PageElementHandler;
import com.hxbd.test.utils.webdriver.WebDriverUtil;

public class PlatformUtil implements UtilService{
    protected String imei;
	private static String EXTENTX_ADD = "EXTENTX_ADD";
	
	public static PageElementHandler settingPro;
	protected String USER_NAME;
    protected String PASS_WORD;
    protected String USER_INFO;
	protected static String test_Env;
	protected static String test_type;
    public static String getTesttype() {
		return test_type;
	}

	public static void setTesttype(String testtype) {
		test_type = testtype;
	}
	private static final String TEST_STORE_URL = "TEST_STORE_URL";    
    public static String getTestEnv() {
		return test_Env;
	}
	/**
	 * 判断字符串是否为空或者NULL
	 * 
	 * @param str
	 *            字符串
	 * @return Boolean
	 */
	public static Boolean isStrEmpty(String str) {
		if (str == null || str.trim().length() == 0) {
			return true;
		} else {
			return false;
		}
	}
	


	/**
	 * 将字符串转换成MD5编码
	 * 
	 * @param inStr
	 * @return String
	 */
	public static String string2MD5(String inStr) {
		String re_md5 = new String();
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(inStr.getBytes());
			byte b[] = md.digest();

			int i;

			StringBuffer buf = new StringBuffer("");
			for (int offset = 0; offset < b.length; offset++) {
				i = b[offset];
				if (i < 0)
					i += 256;
				if (i < 16)
					buf.append("0");
				buf.append(Integer.toHexString(i));
			}

			re_md5 = buf.toString().toUpperCase();

		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return re_md5;
	}
	/**
	 * 比较时间先后
	 * 
	 * @param date1
	 * @param date2
	 * @param dateFormat
	 * @return Boolean
	 */
	public static Boolean isBeforeDate(String date1, String date2, String dateFormat) {
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat, Locale.CHINA);
		Date d1 = null;
		Date d2 = null;
		try {
			d1 = sdf.parse(date1);
			d2 = sdf.parse(date2);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return d1.before(d2);
	}

	/**
	 * 把文本编码为Html代码
	 * 
	 * @param target
	 * @return 编码后的字符串
	 */
	public static String htmEncode(String target) {
		StringBuffer stringbuffer = new StringBuffer();
		int j = target.length();
		for (int i = 0; i < j; i++) {
			char c = target.charAt(i);
			switch (c) {
			case 60:
				stringbuffer.append("<");
				break;
			case 62:
				stringbuffer.append(">");
				break;
			case 38:
				stringbuffer.append("&");
				break;
			case 34:
				stringbuffer.append("\"");
				break;
			case 169:
				stringbuffer.append("©");
				break;
			case 174:
				stringbuffer.append("®");
				break;
			case 165:
				stringbuffer.append("¥");
				break;
			case 8364:
				stringbuffer.append("€");
				break;
			case 8482:
				stringbuffer.append("™");
				break;
			case 13:
				if (i < j - 1 && target.charAt(i + 1) == 10) {
					stringbuffer.append("<br>");
					i++;
				}
				break;
			case 32:
				if (i < j - 1 && target.charAt(i + 1) == ' ') {
					stringbuffer.append(" &nbsp;");
					i++;
					break;
				}
			default:
				stringbuffer.append(c);
				break;
			}
		}
		return new String(stringbuffer.toString());
	}


	/**
	 * 把中文转成Unicode码
	 * 
	 * @param str
	 * @return String
	 */
	public static String chinaToUnicode(String str) {
		String result = "";
		for (int i = 0; i < str.length(); i++) {
			int chr1 = str.charAt(i);
			if (chr1 >= 19968 && chr1 <= 171941) {// 汉字范围 \u4e00-\u9fa5 (中文)
				result += "\\u" + Integer.toHexString(chr1);
			} else {
				result += str.charAt(i);
			}
		}
		return result;
	}

	protected static String getURLEncoder(String dest) throws UnsupportedEncodingException {
		return URLEncoder.encode(dest, "UTF-8");
	}

    /**
     * 获得测试入口url
     * @return url(String)
     */
    public static String getTestStoreURL () {
    	return settingPro.getProperty(TEST_STORE_URL);
    }
    /**
     * 获得测试数据文件路径
     * @param filepathPro 相对路径在配置文件中对于的key
     * @return String
     */
    protected static String getTestDataBasicFile(String filepathPro) {
    	return CommonUtils.getFilePath(settingPro.getProperty(filepathPro));
	}
	private static final String REPORT_LOCATION = "REPORT_LOCATION";
	protected static String reportLocation =PageElementHandler.getStoreSettingProperties().getProperty(REPORT_LOCATION);
	protected static ExtentReports extent = null;
	protected static Map<String, ExtentTest> m2 = new HashMap<String, ExtentTest>();
	protected static Map<Integer, ExtentTest> m = new HashMap<Integer, ExtentTest>();
	protected static AtomicInteger count = new AtomicInteger();
	protected static Set<TestDicBean> dicset = new ConcurrentHashSet<TestDicBean>();
	public static Set<TestDicBean> getDicset() {
		return dicset;
	}

	public static ExtentReports getextent() {
		return extent;
	}

	public static Map<String, ExtentTest> getM2() {
		return m2;
	}
    public static ExtentTest startTest(String testName) {
		ExtentTest test = extent.createTest(testName, "");
		m2.put(testName, test);
		m.put(count.incrementAndGet(), test);
		return test;
	}

	public static ExtentTest startTest(String testName, String desc) {
		ExtentTest test = extent.createTest(testName, desc);
		m2.put(testName, test);
		m.put(count.incrementAndGet(), test);
		return test;
	}

	protected void endtest() {
		for (int i = 1; i <= m.size(); i++) {
			ExtentTest t = m.get(i);
			Test t1 = t.getModel();
			t1.end();
			System.out.println("关闭测试:" + i + " : " + t.toString());
		}
	}
	
	protected void initExtent(String testEnv,String projectname) {
		try {
			ExtentHtmlReporter htmlReporter = new ExtentHtmlReporter(reportLocation);
	        Properties pro = new Properties();
	        pro.load(new FileReader(CommonUtils
					.getFilePath("extent/extent-config.xml")));
	        htmlReporter.loadConfig(pro);
	        htmlReporter.config().setCSS(org.apache.commons.io.FileUtils.readFileToString(new File(CommonUtils.getFilePath(
	        		PageElementHandler.getStoreSettingProperties().getProperty("extentCSS_profile"))), "UTF-8"));
	        htmlReporter.config().setJS(org.apache.commons.io.FileUtils.readFileToString(new File(CommonUtils.getFilePath(
	        		PageElementHandler.getStoreSettingProperties().getProperty("extentJS_profile"))), "UTF-8"));
	        htmlReporter.config().setTestViewChartLocation(ChartLocation.TOP);
	        htmlReporter.config().setChartVisibilityOnOpen(true);
	        htmlReporter.config().setEncoding("UTF-8");
	        htmlReporter.config().setReportName(projectname);
	        htmlReporter.config().setTheme(Theme.DARK);
	        extent = new ExtentReports();
	        ExtentXReporter extentxReporter = null;
	        String extenntadd = PageElementHandler.getStoreSettingProperties().getProperty(EXTENTX_ADD);
			if (getIpAdd().equals(extenntadd)) {
//				extent.x(extenntadd, 27017);
				extentxReporter = new ExtentXReporter(extenntadd, 27017);
				extentxReporter.config().setProjectName(projectname);
				extentxReporter.config().setReportName(projectname+"_"+CommonUtils.now("yyyyMMddHHmmss"));
//				extentxReporter.start();
			}
			if (null != extentxReporter) {
		        extent.attachReporter(htmlReporter,extentxReporter);
			}
			else {
		        extent.attachReporter(htmlReporter);
			}
			extent.setSystemInfo("操作系统", System.getProperty("os.name"));
			extent.setSystemInfo("测试环境", testEnv);
//			extent.loadConfig(new File(CommonUtils
//					.getFilePath("/Config/extent-config.xml")));
//			extent.assignProject(projectname);
//			extent.addSystemInfo("Environment", testEnv);
//			extent.startReporter(ReporterType.DB, reportLocation);
		} catch (ExtentTestInterruptedException | IOException e) {
			Assert.fail(e.toString());
		}
	}
	/**
	 * 获得当前测试类名
	 * @param tr 测试结果对象
	 * @return String
	 */
	public static String getTestClassName (ITestResult tr) {
		String temp = tr.getInstanceName();
		String temp2[] = temp.split("\\.");
		return temp2[temp2.length - 1];
	}
	    /** 
	     * 根据网卡获得IP地址 
	     * @return 
	     * @throws SocketException 
	     * @throws UnknownHostException 
	     */  
	    public  static String getIpAdd() throws SocketException, UnknownHostException{  
	        String ip="";  
	        for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {  
	            NetworkInterface intf = en.nextElement();  
	            String name = intf.getName();  
	            if (!name.contains("docker") && !name.contains("lo")) {  
	                for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {  
	                    //获得IP  
	                    InetAddress inetAddress = enumIpAddr.nextElement();  
	                    if (!inetAddress.isLoopbackAddress()) {  
	                        String ipaddress = inetAddress.getHostAddress().toString();  
	                        if (!ipaddress.contains("::") && !ipaddress.contains("0:0:") && !ipaddress.contains("fe80")) {  	                              
	                            if(!"127.0.0.1".equals(ip)){  
	                                ip = ipaddress;  
	                            }  
	                        }  
	                    }  
	                }  
	            }  
	        }  
	        return ip;  
	    }
	    
		/**
		 * 根据某文件及它与另一文件的相对路径获得另一文件
		 * 
		 * @param file1
		 * @param relativefilepath
		 * @return
		 */
		public static File getRelativePathFile(String file1, String relativefilepath) {
			File file = null;
			File f = new File(file1).getParentFile();
			if (relativefilepath.startsWith("..\\")) {
				String[] s = relativefilepath.split("\\.\\.\\\\");
				for (int i = 0; i < s.length - 1; i++) {
					f = f.getParentFile();
				}
				file = new File(f, s[s.length - 1]);
			} else {
				file = new File(f, relativefilepath);
			}
			return file;
		}

		//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// 以下为取值型函数,供excel调用

		/**
		 * 取当前时间
		 * 
		 * @param format
		 *            时间格式
		 * @return
		 */
		public static String now(String format) {
			Date d = new Date();
			SimpleDateFormat sdf = new SimpleDateFormat(format);
			return sdf.format(d);
		}

		/**
		 * 返回当前时间前/后多少秒/天/年/月等
		 * 
		 * @param format
		 *            返回时间格式
		 * @param interval
		 *            时间间隔
		 * @param calendarType
		 *            calender的时间类型 如Calender.Minute
		 * @return
		 */
		public static String nowBeforeOrAfter(String format, String interval, String calendarType) {
			SimpleDateFormat sdf = new SimpleDateFormat(format);
			Calendar calender = Calendar.getInstance();
			calender.add(Integer.parseInt(calendarType), Integer.parseInt(interval));
			return sdf.format(calender.getTime());
		}

		/**
		 * 返回当前13位时间戳
		 * @return
		 */
		public static long getTimestampNow() {
			Calendar calender = Calendar.getInstance();
			return calender.getTimeInMillis();
		}
		/**
		 * 返回某时间前/后多少秒/天/年/月等
		 * 
		 * @param time
		 * @param format
		 *            返回时间格式
		 * @param interval
		 *            时间间隔
		 * @param calendarType
		 *            calender的时间类型 如Calender.Minute
		 * @return
		 * @throws ParseException
		 */
		public static String getTimeBeforeOrAfter(String time, String format, String interval, String calendarType)
				throws ParseException {
			SimpleDateFormat sdf = new SimpleDateFormat(format);
			Calendar calender = Calendar.getInstance();
			calender.setTime(sdf.parse(time));
			calender.add(Integer.parseInt(calendarType), Integer.parseInt(interval));
			return sdf.format(calender.getTime());
		}

		/**
		 * 获得昨天的0点
		 * 
		 * @return String
		 */
		public static String yesterDayStart() {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
			String sd = sdf.format(new Date(new Date().getTime() - 24 * 60 * 60 * 1000));
			return sd;
		}

		/**
		 * 获得昨天的23点59粉59秒
		 * 
		 * @return String
		 */
		public static String yesterDayEnd() {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
			String sd = sdf.format(new Date(new Date().getTime() - 24 * 60 * 60 * 1000));
			return sd;
		}

		/**
		 * 获得当前时间
		 * 
		 * @return String
		 */
		public static String now() {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String sd = sdf.format(new Date(new Date().getTime()));
			return sd;
		}

		/**
		 * 获得当天的0点0粉0秒
		 * 
		 * @return String
		 */
		public static String todayStart() {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
			String sd = sdf.format(new Date(new Date().getTime()));
			return sd;
		}

		/**
		 * 获得第二天的0点0粉0秒
		 * 
		 * @return String
		 */
		public static String todayEnd() {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
			String sd = sdf.format(new Date(new Date().getTime()));
			return sd;
		}

		/**
		 * 获得当前时间的前几天
		 * 
		 * @param lastInt
		 *            前几天
		 * @return String
		 */
		public static String nowBeforeDays(String lastInt) {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String sd = sdf.format(new Date(new Date().getTime() - Integer.parseInt(lastInt) * 24 * 60 * 60 * 1000));
			return sd;
		}

		/**
		 * 获得当前时间的后几天
		 * 
		 * @param afterInt
		 *            后几天
		 * @return String
		 */
		public static String nowAfterDays(String afterInt) {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String sd = sdf.format(new Date(new Date().getTime() + Integer.parseInt(afterInt) * 24 * 60 * 60 * 1000));
			return sd;
		}

		/**
		 * 比较time2与time1时间间隔,精确到s
		 * 
		 * @param fstTime
		 *            time1
		 * @param sndTime
		 *            time2
		 * @param format
		 *            时间格式
		 * @return
		 */
		public static long getTimeDif(String fstTime, String sndTime, String format) {
			DateFormat df = new SimpleDateFormat(format);
			long diff = 0;
			try {
				Date d1 = df.parse(fstTime);
				Date d2 = df.parse(sndTime);
				diff = Math.abs((d2.getTime() - d1.getTime()) / 1000);
			} catch (ParseException e) {
				e.printStackTrace();
			}
			return diff;
		}

		private static final String allSpecialChar = "[`~!@#$%^&*()_\\-+=<>?:\"{}|,.\\/;'\\\\[\\]·~！@#￥%……&*（）——\\-+={}|《》？：“”【】、；‘’，。、]";

		/**
		 * 将特殊字符做正则处理
		 * 
		 * @param s
		 * @return
		 */
		public static String replaceSpecialChar(String s) {
			String tmpstr = "";
			while (!s.isEmpty()) {
				// 取字符串首字母
				String character = s.substring(0, 1);
				// 剩余的字符串
				s = s.substring(1);
				if (allSpecialChar.contains(character)) {
					character = StringUtils.replaceOnce(character, character, "\\" + character);
				}
				tmpstr += character;
			}
			return tmpstr;
		}

		/**
		 * 获得当前时间的前几天
		 * 
		 * @param lastInt
		 *            前几天
		 * @return String
		 */
		public static String nowBeforeOrAfterStart(String format, String interval, String calendarType, int hour,
				int min, int sec) {
			SimpleDateFormat sdf = new SimpleDateFormat(format);
			Calendar calender = Calendar.getInstance();
			calender.add(Integer.parseInt(calendarType), Integer.parseInt(interval));
			calender.set(Calendar.HOUR_OF_DAY, hour);
			calender.set(Calendar.MINUTE, min);
			calender.set(Calendar.SECOND, sec);
			return sdf.format(calender.getTime());
		}

		protected static Map<String, Map<Integer, Date>> msg_map = new HashMap<String, Map<Integer, Date>>();

		public static Map<String, Map<Integer, Date>> getMsg_map() {
			return msg_map;
		}

		/**
		 * 获得报文发送时间
		 * 
		 * @param msgtype
		 *            获取报文类型(设置到容器时的key)
		 * @param index
		 *            第几条
		 * @param format
		 *            获取报文返回时间格式
		 * @return String
		 */
		public static String getMsgTime(String msgtype, String index, String format) {
			Date d = msg_map.get(msgtype).get(Integer.parseInt(index));
			SimpleDateFormat timeformat = new SimpleDateFormat(format);
			return timeformat.format(d);
		}

		/**
		 * 获得报文发送时间(默认返回时间格式为yyyy-MM-dd HH:mm:ss)
		 * 
		 * @param msgtype
		 *            获取报文类型(设置到容器时的key)
		 * @param index
		 *            第几条
		 * @return String
		 */
		public static String getMsgTime(String msgtype, String index) {
			Date d = msg_map.get(msgtype).get(Integer.parseInt(index));
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			return format.format(d);
		}

		/**
		 * 获得报文发送时间的时间戳
		 * 
		 * @param msgtype
		 *            获取报文类型(设置到容器时的key)
		 * @param index
		 *            第几条
		 * @param timeunit
		 *            0:时间戳取s 1:时间戳取ms
		 * @return long
		 */
		public static long getMsgTimeStamp(String msgtype, String index, String timeunit) {
			Date d = msg_map.get(msgtype).get(Integer.parseInt(index));
			long timstamp = 0;
			int unit = Integer.parseInt(timeunit);
			if (unit != 0 && unit != 1) {
				Assert.fail("timeunit只能为0或者1");
			}
			if (unit == 0) {
				timstamp = d.getTime() / 1000;
			} else if (unit == 1) {
				timstamp = d.getTime();
			}
			return timstamp;
		}
		

		/**
		 * 生成校验码-针对PHP接口
		 * 
		 * @param app_key
		 * @param method
		 * @param timestamp
		 * @param data
		 * @return String 校验码
		 */
		public String sign1(String app_key, String app_secret, String method, String timestamp, String data) {
			String MD5String = app_secret + "app_key" + app_key + "data" + data + "method" + method + "timestamp"
					+ timestamp + app_secret;
			return string2MD5(MD5String);
		}

		/**
		 * 签名方法，用于生成签名。
		 * 
		 * @param jsonParams
		 *            传给服务器的参数（json）
		 * @param secret
		 *            分配给您的APP_SECRET
		 * @return String
		 */
		public static String sign2(String app_key, String method, String format, String timestamp, String jsonParams,
				String secret) {
			JSONObject jo = JSON.parseObject(jsonParams);
			Map<String, String> m = new HashMap<String, String>();
			for (Object key : jo.keySet()) {
				m.put(key.toString(), jo.get(key).toString());
			}
			m.put("app_key", app_key);
			m.put("method", method);
			m.put("format", format);
			m.put("timestamp", timestamp);
			return sign2(m, secret);
		}

		/*
		 * 签名方法，用于生成签名。
		 * 
		 * @param params 传给服务器的参数
		 * 
		 * @param secret 分配给您的APP_SECRET
		 */
		public static String sign2(Map params, String secret) {
			String result = null;
			if (params == null)
				return result;

			// 将参数按key排序
			Set<String> keys = params.keySet();
			String[] ps = new String[keys.size()];
			int i = 0;
			for (String key : keys) {
				Object value = params.get(key);
				if (value != null) {
					ps[i++] = key + value.toString();
				}
			}
			if (i == 0)
				return result;
			String[] ss = new String[i];
			System.arraycopy(ps, 0, ss, 0, i);
			Arrays.sort(ss);

			// 将secret同时放在头尾，拼成字符串
			StringBuilder orgin = new StringBuilder(secret);
			for (int j = 0; j < ss.length; j++) {
				orgin.append(ss[j]);
			}
			orgin.append(secret);

			try {
				MessageDigest md = MessageDigest.getInstance("MD5");
				result = byte2hex(md.digest(orgin.toString().getBytes("utf-8")));
			} catch (Exception ex) {
				throw new java.lang.RuntimeException("sign error !");
			}
			return result;
		}

		/*
		 * 二行制转字符串
		 */
		private static String byte2hex(byte[] b) {

			StringBuffer hs = new StringBuffer();
			String stmp = "";
			for (int n = 0; n < b.length; n++) {
				stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
				if (stmp.length() == 1)
					hs.append("0").append(stmp);
				else
					hs.append(stmp);
			}
			return hs.toString().toUpperCase();
		}
}
